package com.example.forum.services.impl;

import com.example.forum.common.AppResult;
import com.example.forum.common.ResultCode;
import com.example.forum.dao.UserMapper;
import com.example.forum.exception.ApplicationException;
import com.example.forum.model.User;
import com.example.forum.services.IUserService;
import com.example.forum.utils.MD5Util;
import com.example.forum.utils.StringUtil;
import com.example.forum.utils.UUIDUtils;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.graphql.GraphQlProperties;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.UUID;


@Slf4j
@Service
public class UserServiceImpl implements IUserService {

    @Autowired
    private UserMapper userMapper;


    //判断传入的数据是否为空
    @Override
    public void createNormalUser(User user) {
        if (user == null || StringUtil.isEmpty(user.getUsername())
                || StringUtil.isEmpty(user.getPassword())
                || StringUtil.isEmpty(user.getNickname())) {
            log.warn(ResultCode.ERROR_IS_NULL.toString());
            throw new ApplicationException(AppResult.failed(ResultCode.ERROR_IS_NULL));
        }

        //判断传入的用户名，是否以及存在
        User user1 = userMapper.selectByUserName(user.getUsername());
        if (user1 != null) {
            log.info(ResultCode.FAILED_USER_EXISTS.toString());
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_EXISTS));
        }

        //都没有问题的情况下，再进行数据的插入
        user.setGender((byte) 2);
        user.setIsAdmin((byte) 0);
        user.setAvatarUrl(null);
        user.setArticleCount(0);
        user.setState((byte) 0);
        user.setDeleteState((byte) 0);
        Date date = new Date();
        user.setCreateTime(date);
        user.setUpdateTime(date);
        int row = userMapper.insertSelective(user);
        if (row != 1) {
            log.info(ResultCode.FAILED_CREATE.toString() + "username = " + user.getUsername());
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_CREATE));
        }
        log.info("新增用户成功 username = " + user.getUsername());

    }


    @Override
    public User selectByName(String username) {
        if (StringUtil.isEmpty(username)) {
            log.warn(ResultCode.ERROR_IS_NULL.toString());
            throw new ApplicationException(AppResult.failed(ResultCode.ERROR_IS_NULL));
        }
        return userMapper.selectByUserName(username);

    }

    @Override
    public User login(String username, String password) {
        if (StringUtil.isEmpty(username) || StringUtil.isEmpty(password)) {
            log.warn(ResultCode.ERROR_IS_NULL.toString());
            throw new ApplicationException(AppResult.failed(ResultCode.ERROR_IS_NULL));
        }
        User user = selectByName(username);
        if (user == null) {
            log.warn(ResultCode.FAILED_USER_NOT_EXISTS.toString());
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_NOT_EXISTS));

        }
        //传入的数据没问题 ，将密码进行加密，和数据库中加密的数据进行对比
        String scaryPassword = MD5Util.md5Salt(password, user.getSalt());
        if (!scaryPassword.equalsIgnoreCase(user.getPassword())) {
            log.info("输入加密后密码的值为" + scaryPassword);
            ;
            log.warn(ResultCode.FAILED_LOGIN.toString());
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_LOGIN));

        }
        return user;

    }

    @Override
    public User SelectById(Long id) {
        if (id == null) {
            log.info(ResultCode.FAILED_NOT_EXISTS.toString());
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_NOT_EXISTS));
        }
        User user = userMapper.selectByPrimaryKey(id);
        if (user == null) {
            log.info("不存在该用户");
        }
        return user;

    }

    @Override
    public void addOnceArticleCountById(Long id) {          //个人的发帖数量的跟新
        if (id == null || id <= 0) {
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }
        User result = userMapper.selectByPrimaryKey(id);
        User user = new User();
        if (result == null) {
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }
        user.setId(result.getId());
        user.setArticleCount(result.getArticleCount() + 1);
        int row = userMapper.updateByPrimaryKeySelective(user);
        if (row != 1) {
            log.warn("更新操作失败");
        }
    }

    @Override
    public void subOneArticleCountById(Long id) {
        if (id == null || id <= 0) {
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }
        User result = userMapper.selectByPrimaryKey(id);
        User user = new User();
        if (result == null) {
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }
        user.setId(result.getId());
        user.setArticleCount(result.getArticleCount() - 1);
        //用户发帖量不能小于0
        if (user.getArticleCount() < 0) {
            user.setArticleCount(0);
        }
        int row = userMapper.updateByPrimaryKeySelective(user);
        if (row != 1) {
            log.warn("更新操作失败");
        }

    }

    @Override
    public void modifyInfo(User user) {
        if (user == null || user.getId() == null || user.getId() <= 0) {
            log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }

        //查询当前用户的信息,校验是否存在
        User existUser = userMapper.selectByPrimaryKey(user.getId());
        if (existUser == null) {
            log.warn(ResultCode.FAILED_USER_NOT_EXISTS.toString());
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_NOT_EXISTS));
        }

        //定义一个标志为，如果传入的user中有需要更改的元素，将其改为true
        boolean checkAttr = false;

        //构造跟新对象
        User update = new User();
        update.setId(user.getId());

        //对每个参数进行校验  用户名
        if (!StringUtil.isEmpty(user.getUsername())
                && !user.getUsername().equals(existUser.getUsername())) {
            //对要更新的用户名进行唯一校验，如果数据库中已存在当前用户名是不能更改的
            User user1 = userMapper.selectByUserName(user.getUsername());
            if (user1 != null) {
                //用户名以及存在
                log.warn(ResultCode.FAILED_USER_EXISTS.toString());
                throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_EXISTS));
            }
            //修改用户名，放入构造的跟新对象
            update.setUsername(user.getUsername());
            //跟新标志为
            checkAttr = true;
        }
        //对昵称进行校验
        if (!StringUtil.isEmpty(user.getNickname())
                && !user.getNickname().equals(existUser.getNickname())) {
            update.setNickname(user.getNickname());
            checkAttr = true;
        }

        //性别上的校验
        if (user.getGender() != null && user.getGender() != existUser.getGender()) {
            update.setGender(user.getGender());

            //性别的合法校验
            if (update.getGender() > 2 || update.getGender() < 0) {
                update.setGender((byte) 2);
            }
            // 更新标志位
            checkAttr = true;
        }

        //邮箱额校验
        if (!StringUtil.isEmpty(user.getEmail())
                && !user.getEmail().equals(existUser.getEmail())) {
            update.setEmail(user.getEmail());
            checkAttr = true;
        }

        //电话号码的校验
        if (!StringUtil.isEmpty(user.getPhoneNum())
                && !user.getPhoneNum().equals(existUser.getPhoneNum())) {
            update.setPhoneNum(user.getPhoneNum());
            checkAttr = true;
        }

        //校验个人简介
        // 10. 校验个⼈简介
        if (!StringUtil.isEmpty(user.getRemark())
                && !user.getRemark().equals(existUser.getRemark())) {
            // 设置电话号码
            update.setRemark(user.getRemark());
            // 更新标志位
            checkAttr = true;
        }
        if (checkAttr == false) {
            log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }

        int i = userMapper.updateByPrimaryKeySelective(update);
        if (i != 1) {
            log.warn(ResultCode.FAILED.toString() + ", 受影响的⾏数不等于 1 .");
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED));
        }

    }

    @Override
    public void modifyPassword(Long id, String newPassword, String oldPassword) {
        if(id==null||id<=0||StringUtil.isEmpty(newPassword)||StringUtil.isEmpty(oldPassword)){
            log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));

        }
        User user = userMapper.selectByPrimaryKey(id);
        if(user==null||user.getDeleteState()==1){
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_UNAUTHORIZED));
        }

        //参数校验没问题后
        //判断传入的老密码和原来密码是否相同
        String oldEncryPassword = MD5Util.md5Salt(oldPassword, user.getSalt());
        if(!oldEncryPassword.equals(user.getPassword())){
            log.warn(ResultCode.FAILED_TWO_PWD_NOT_SAME.toString());
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_TWO_PWD_NOT_SAME));

        }
        //设置新盐,设置新密码
        String salt = UUIDUtils.uuid_32();
        String newEncyPawwsord = MD5Util.md5Salt(newPassword, salt);

        //构建更新对象
        User modifyUser = new User();
        modifyUser.setId(user.getId());
        modifyUser.setPassword(newEncyPawwsord);
        modifyUser.setSalt(salt);
        modifyUser.setUpdateTime(new Date());

        //进行更新操作
        userMapper.updateByPrimaryKeySelective(modifyUser);


    }
}
